# liver_calculator.py
"""
肝脏参数计算器 - 主模块
"""
import numpy as np
import pandas as pd

from .liver_parameters import (LIVER_VOLUME_PARAMS, HPGL_PARAMS, MPPGL_PARAMS, 
                             CPPGL_PARAMS, S9PPGL_PARAMS, FORMULA_SUMMARY)
from .liver_volume import calculate_liver_volume, calculate_liver_weight
from .HPGL import calculate_hpgl
from .MPPGL import calculate_mppgl
from .CPPGLS9PPGL import calculate_cppgl, calculate_s9ppgl

class LiverParametersCalculator:
    """
    肝脏参数计算模块
    
    计算流程:
    1. 从人口统计学模块接收BSA和年龄数据
    2. 计算肝脏体积和重量
    3. 计算HPGL (每克肝脏的肝细胞数量)
    4. 计算MPPGL (每克肝脏的微粒体蛋白含量)
    5. 计算CPPGL (每克肝脏的细胞质蛋白含量)
    6. 计算S9PPGL (每克肝脏的S9蛋白含量)
    
    输出:
    - Liver_Volume_L: 肝脏体积(L)
    - Liver_Weight_g: 肝脏重量(g)
    - HPGL_10e6_cells_per_g: 每克肝脏的肝细胞数量(10^6 cells/g)
    - MPPGL_mg_per_g: 每克肝脏的微粒体蛋白含量(mg/g)
    - CPPGL_mg_per_g: 每克肝脏的细胞质蛋白含量(mg/g)
    - S9PPGL_mg_per_g: 每克肝脏的S9蛋白含量(mg/g)
    """
    
    def __init__(self):
        """初始化计算参数"""
        # 加载默认参数
        self.liver_volume_params = LIVER_VOLUME_PARAMS.copy()
        self.hpgl_params = HPGL_PARAMS.copy()
        self.mppgl_params = MPPGL_PARAMS.copy()
        self.cppgl_params = CPPGL_PARAMS.copy()
        self.s9ppgl_params = S9PPGL_PARAMS.copy()
        
        # 设置计算所需的主要参数
        self.bsa_coefficient = self.liver_volume_params['bsa_coefficient']
        self.bsa_exponent = self.liver_volume_params['bsa_exponent']
        self.liver_volume_cv = self.liver_volume_params['liver_volume_cv']
        self.liver_density = self.liver_volume_params['liver_density']
        
        self.hpgl_baseline = self.hpgl_params['baseline']
        self.hpgl_age_coefficient = self.hpgl_params['age_coefficient']
        self.hpgl_cv_gt20 = self.hpgl_params['cv_gt20']
        self.hpgl_cv_lt20 = self.hpgl_params['cv_lt20']
        
        self.mppgl_baseline = self.mppgl_params['baseline']
        self.mppgl_c1 = self.mppgl_params['c1']
        self.mppgl_c2 = self.mppgl_params['c2']
        self.mppgl_c3 = self.mppgl_params['c3']
        self.mppgl_cv = self.mppgl_params['cv']
        
        self.cppgl_baseline = self.cppgl_params['baseline']
        self.cppgl_slope = self.cppgl_params['slope']
        self.cppgl_cv = self.cppgl_params['cv']
        
        self.s9ppgl_baseline = self.s9ppgl_params['baseline']
        self.s9ppgl_cv = self.s9ppgl_params['cv']
    
    def set_parameters(self, params_dict):
        """设置计算参数"""
        if params_dict is None:
            return
            
        for key, value in params_dict.items():
            if hasattr(self, key):
                setattr(self, key, value)
    
    def calculate_liver_volume(self, bsa):
        """计算肝脏体积(包含变异)"""
        return calculate_liver_volume(bsa, self.bsa_coefficient, self.bsa_exponent, self.liver_volume_cv)
    
    def calculate_liver_weight(self, liver_volume):
        """根据肝脏体积计算肝脏重量"""
        return calculate_liver_weight(liver_volume, self.liver_density)
    
    def calculate_hpgl(self, age):
        """计算每克肝脏的肝细胞数量(HPGL)，包含变异"""
        return calculate_hpgl(age, self.hpgl_baseline, self.hpgl_age_coefficient, 
                             self.hpgl_cv_lt20, self.hpgl_cv_gt20)
    
    def calculate_mppgl(self, age):
        """计算每克肝脏的微粒体蛋白含量(MPPGL)，包含变异"""
        return calculate_mppgl(age, self.mppgl_baseline, self.mppgl_c1, self.mppgl_c2, 
                              self.mppgl_c3, self.mppgl_params['mean'], self.mppgl_cv)
    
    def calculate_cppgl(self, mppgl):
        """计算每克肝脏的细胞质蛋白含量(CPPGL)，包含变异"""
        return calculate_cppgl(mppgl, self.cppgl_baseline, self.cppgl_slope, self.cppgl_cv)
    
    def calculate_s9ppgl(self, mppgl, cppgl):
        """计算每克肝脏的S9蛋白含量(S9PPGL)"""
        return calculate_s9ppgl(mppgl, cppgl)
    
    def process_demographic_data(self, demographic_df, bsa_column='BSA (m2)', age_column='Age(years)', random_seed=None):
        """
        处理人口统计学数据，计算肝脏参数
        
        参数:
        demographic_df: 包含BSA和年龄的DataFrame
        bsa_column: BSA列名
        age_column: 年龄列名
        random_seed: 随机种子(用于结果可重复性)
        
        返回:
        添加了肝脏参数的DataFrame
        """
        # 检查必要列是否存在
        if bsa_column not in demographic_df.columns:
            raise ValueError(f"输入数据缺少BSA列: {bsa_column}")
        if age_column not in demographic_df.columns:
            raise ValueError(f"输入数据缺少年龄列: {age_column}")
        
        # 设置随机种子
        if random_seed is not None:
            np.random.seed(random_seed)
        
        # 创建结果数据框
        result_df = demographic_df.copy()
        
        # 存储计算结果的列表
        liver_volumes = []          # 肝脏体积
        liver_weights = []          # 肝脏重量
        hpgl_values = []            # HPGL值
        mppgl_values = []           # MPPGL值
        cppgl_values = []           # CPPGL值
        s9ppgl_values = []          # S9PPGL值
        
        # 逐个处理每个受试者
        for i, row in demographic_df.iterrows():
            bsa = row[bsa_column]
            age = row[age_column]
            
            # 计算肝脏体积(含变异)
            liver_volume = self.calculate_liver_volume(bsa)
            liver_volumes.append(liver_volume)
            
            # 计算肝脏重量
            liver_weight = self.calculate_liver_weight(liver_volume)
            liver_weights.append(liver_weight)
            
            # 计算HPGL(含变异)
            hpgl = self.calculate_hpgl(age)
            hpgl_values.append(hpgl)
            
            # 计算MPPGL(含变异)
            mppgl = self.calculate_mppgl(age)
            mppgl_values.append(mppgl)
            
            # 计算CPPGL(含变异)
            cppgl = self.calculate_cppgl(mppgl)
            cppgl_values.append(cppgl)
            
            # 计算S9PPGL
            s9ppgl = self.calculate_s9ppgl(mppgl, cppgl)
            s9ppgl_values.append(s9ppgl)
        
        # 将计算结果添加到数据框
        result_df['Liver_Volume_L'] = liver_volumes
        result_df['Liver_Weight_g'] = liver_weights
        result_df['HPGL_10e6_cells_per_g'] = hpgl_values
        result_df['MPPGL_mg_per_g'] = mppgl_values
        result_df['CPPGL_mg_per_g'] = cppgl_values
        result_df['S9PPGL_mg_per_g'] = s9ppgl_values
        
        return result_df

    def get_formula_summary(self):
        """获取所有计算公式的摘要"""
        return FORMULA_SUMMARY

if __name__ == "__main__":
    import pandas as pd
    # 构造测试数据
    test_df = pd.DataFrame({
        'id': [1, 2],
        'BSA (m2)': [1.7, 1.8],
        'Age(years)': [30, 40]
    })
    calc = LiverParametersCalculator()
    result = calc.process_demographic_data(test_df, bsa_column='BSA (m2)', age_column='Age(years)')
    print(result)
